package websocket

import (
	"container/list"
	"encoding/json"
	"log"
	"net/http"
	"time"
	"zhejianglab/gin-apiserver/model"
	pb "zhejianglab/gin-apiserver/proto"

	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{} // use default options
var connList list.List
var messageChan chan []byte

type WsMessage struct {
	wsType           int64
	resposeWsMessage ResposeWsMessage
}

type SearchInfo struct {
	Search pb.AlgorithmResult `json:"search"`
}

type JobInfo struct {
	Job model.JobInfo `json:"job"`
}
type ResposeWsMessage struct {
	JobInfo    JobInfo    `json:"job_info"`
	SearchInfo SearchInfo `json:"search_info"`
}

func init() {
	messageChan = make(chan []byte, 50)
}
func SetJObWsMessage(job model.JobInfo) {
	wsMess := WsMessage{}
	wsMess.resposeWsMessage.JobInfo.Job = job
	requestBody, err := json.Marshal(wsMess.resposeWsMessage.JobInfo)
	if err != nil {
		log.Println("Marshal failed!")
	}
	messageChan <- requestBody
}

func SetSearchWsMessage(search *pb.AlgorithmResult) {
	wsMess := WsMessage{}
	wsMess.resposeWsMessage.SearchInfo.Search = *search
	requestBody, err := json.Marshal(wsMess.resposeWsMessage.SearchInfo)
	if err != nil {
		log.Println("Marshal failed!")
	}
	messageChan <- requestBody
}

func WriteBroadcastMessage() {
	for {
		select {
		case message := <-messageChan:
			for conn := connList.Front(); conn != nil; conn = conn.Next() {
				if err := conn.Value.(*websocket.Conn).WriteMessage(websocket.TextMessage, message); err != nil {
					log.Print("WriteMessage Error:", err)
					connList.Remove(conn)
				}
			}
		case <-time.After(time.Millisecond * 10):

		}
	}
}

func wsHandler(w http.ResponseWriter, r *http.Request) {
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Print("upgrade:", err)
		return
	}
	connList.PushBack(conn)
	defer conn.Close()
	/*
		go func(){
			var (err error)
			for{
				if err = conn.WriteMessage(websocket.TextMessage,[]byte("heartbeat"));err != nil{
					log.Print("WriteMessage Error:", err)
					return
				}
				time.Sleep(1*time.Second)
			}
		}()*/

	for {
		if _, message, err := conn.ReadMessage(); err != nil {
			log.Print("ReadMessage Error:", err)
			break
		} else {
			log.Print("ReadMessage:", message)
		}
	}

}
